package com.ruoyi.system.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.DsStudentMapper;
import com.ruoyi.system.domain.DsStudent;
import com.ruoyi.system.service.IDsStudentService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 学生信息Service业务层处理
 *
 * @author tyro
 * @date 2025-03-05
 */
@Service
public class DsStudentServiceImpl implements IDsStudentService
{
    @Autowired
    private DsStudentMapper dsStudentMapper;

    private static final Logger log = LoggerFactory.getLogger(DsStudentServiceImpl.class);

    // 注入用户和用户角色Mapper
    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    // 学生角色ID
    private static final Long STUDENT_ROLE_ID = 100L;

    // ... existing code ...
    /**
     * 查询学生信息
     *
     * @param studentNo 学生信息主键
     * @return 学生信息
     */
    @Override
    public DsStudent selectDsStudentByStudentId(String studentNo)
    {
        return dsStudentMapper.selectDsStudentByStudentId(studentNo);
    }


    /**
     * 查询学生信息
     *
     * @param studentNo 学生信息主键
     * @return 学生信息
     */
    @Override
    public DsStudent selectDsStudentByStudentIdTo(String studentNo)
    {
        return dsStudentMapper.selectDsStudentByStudentIdTo(studentNo);
    }

    /**
     * 查询学生信息列表
     *
     * @param dsStudent 学生信息
     * @return 学生信息
     */
    @Override
    public List<DsStudent> selectDsStudentList(DsStudent dsStudent)
    {
        // 获取当前登录用户ID
        Long userId = SecurityUtils.getUserId();
        LoginUser loginUser = SecurityUtils.getLoginUser();
        System.out.println("User collegeId: " + loginUser.getCollegeId());
        // 如果不是管理员，则添加学院过滤条件
        if(!SecurityUtils.isAdmin(userId)){ // 或使用 SecurityUtils.isAdmin(loginUser.getUser().getUserId())
            dsStudent.setCollegeId(SecurityUtils.getLoginUser().getCollegeId());
        }
        return dsStudentMapper.selectDsStudentList(dsStudent);
    }

    /**
     * 新增学生信息
     *
     * @param dsStudent 学生信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertDsStudent(DsStudent dsStudent)
    {
        // 设置学院ID
        if (dsStudent.getCollegeId() == null) {
            dsStudent.setCollegeId(SecurityUtils.getLoginUser().getCollegeId());
        }
        dsStudent.setCreateTime(DateUtils.getNowDate());
        int rows = dsStudentMapper.insertDsStudent(dsStudent);

        // 为新增学生创建用户账号
        if (rows > 0) {
            String operName = SecurityUtils.getUsername();
            syncUserInfo(dsStudent, operName, false);
        }

        return rows;
    }


    /**
     * 修改学生信息
     *
     * @param dsStudent 学生信息
     * @return 结果
     */
    @Override
    public int updateDsStudent(DsStudent dsStudent)
    {
        dsStudent.setUpdateTime(DateUtils.getNowDate());
        return dsStudentMapper.updateDsStudent(dsStudent);
    }

    /**
     * 批量删除学生信息
     *
     * @param studentIds 需要删除的学生信息主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteDsStudentByStudentIds(String[] studentIds)
    {
        // 先查询所有要删除的学生信息，获取学号
        List<DsStudent> studentList = new ArrayList<>();
        for (String studentId : studentIds) {
            DsStudent student = dsStudentMapper.selectDsStudentByStudentIdTo(studentId);
            if (student != null) {
                studentList.add(student);
            }
        }

        // 删除对应的用户账号
        for (DsStudent student : studentList) {
            deleteUserByStudentNo(student.getStudentNo());
        }

        // 删除学生信息
        return dsStudentMapper.deleteDsStudentByStudentIds(studentIds);
    }

    /**
     * 删除学生信息信息
     *
     * @param studentId 学生信息主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteDsStudentByStudentId(String studentId)
    {
        // 先查询要删除的学生信息，获取学号
        DsStudent student = dsStudentMapper.selectDsStudentByStudentIdTo(studentId);
        if (student != null) {
            // 删除对应的用户账号
            deleteUserByStudentNo(student.getStudentNo());
        } else {
            log.warn("未找到ID为{}的学生记录", studentId);
        }

        // 删除学生信息
        return dsStudentMapper.deleteDsStudentByStudentId(studentId);
    }


    /**
     * 根据学号删除用户账号
     *
     * @param studentNo 学号
     */
    private void deleteUserByStudentNo(String studentNo)
    {
        try {
            // 根据学号查询用户
            SysUser user = sysUserMapper.selectUserByUserName(studentNo);
            if (user != null) {
                // 删除用户角色关联
                sysUserRoleMapper.deleteUserRoleByUserId(user.getUserId());
                // 删除用户
                sysUserMapper.deleteUserById(user.getUserId());
                log.info("成功删除学号为 {} 的用户账号", studentNo);
            }
        } catch (Exception e) {
            log.error("删除学号为 {} 的用户账号失败", studentNo, e);
            throw new ServiceException("删除用户账号失败: " + e.getMessage());
        }
    }


    /**
     * 导入学生数据
     *
     * @param studentList 学生数据列表
     * @param operName 操作者
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importStudentData(List<DsStudent> studentList, String operName) {
        if (StringUtils.isNull(studentList) || studentList.size() == 0) {
            throw new ServiceException("导入学生数据不能为空！");
        }


        long startTime = System.currentTimeMillis();
        int successNum = 0;

        try {
            // 1. 获取所有学号，用于一次性查询
            List<String> allStudentNos = studentList.stream()
                .map(DsStudent::getStudentNo)
                .distinct()
                .collect(Collectors.toList());

            // 2. 一次性查询所有已存在的学生
            Map<String, DsStudent> existingStudentMap = new HashMap<>();
            if (!allStudentNos.isEmpty()) {
                // 分批查询，避免IN子句参数过多
                int batchSize = 500;
                for (int i = 0; i < allStudentNos.size(); i += batchSize) {
                    int endIndex = Math.min(i + batchSize, allStudentNos.size());
                    List<String> batchNos = allStudentNos.subList(i, endIndex);

                    List<DsStudent> existingStudents = dsStudentMapper.selectDsStudentByNos(batchNos);
                    for (DsStudent student : existingStudents) {
                        existingStudentMap.put(student.getStudentNo(), student);
                    }
                }
            }

            // 3. 一次性查询所有用户
            Map<String, SysUser> existingUserMap = new HashMap<>();
            for (String studentNo : allStudentNos) {
                SysUser user = sysUserMapper.selectUserByUserName(studentNo);
                if (user != null) {
                    existingUserMap.put(studentNo, user);
                }
            }

            // 4. 准备批量插入学生数据
            List<DsStudent> toInsertList = new ArrayList<>();
            List<DsStudent> toUpdateList = new ArrayList<>();

            // 5. 用户角色关联列表
            List<SysUserRole> userRoleList = new ArrayList<>();

            // 当前时间
            Date now = DateUtils.getNowDate();

            // 6. 处理每条数据
            for (DsStudent student : studentList) {
                // 设置学院ID
                if (student.getCollegeId() == null) {
                    student.setCollegeId(SecurityUtils.getLoginUser().getCollegeId());
                }
                student.setCreateBy(operName);
                student.setCreateTime(now);
                student.setDelFlag("0");

                DsStudent existingStudent = existingStudentMap.get(student.getStudentNo());
                if (existingStudent != null) {
                    // 需要更新的学生
                    student.setStudentId(existingStudent.getStudentId());
                    student.setUpdateBy(operName);
                    student.setUpdateTime(now);
                    toUpdateList.add(student);

                    // 更新对应的用户
                    SysUser existingUser = existingUserMap.get(student.getStudentNo());
                    if (existingUser != null) {
                        existingUser.setNickName(student.getStudentName());
                        existingUser.setUpdateBy(operName);
                        existingUser.setUpdateTime(now);

                        if (StringUtils.isNotEmpty(student.getStudentSex())) {
                            existingUser.setSex("男".equals(student.getStudentSex()) ? "0" : "1");
                        }

                        if (StringUtils.isNotEmpty(student.getStudentPassword())) {
                            existingUser.setPassword(SecurityUtils.encryptPassword(student.getStudentPassword()));
                        }

                        // 单条更新用户
                        sysUserMapper.updateUser(existingUser);
                    }
                } else {
                    // 需要新增的学生
                    toInsertList.add(student);
                }

                successNum++;
            }

            // 7. 批量插入学生
            if (!toInsertList.isEmpty()) {
                dsStudentMapper.batchInsertStudent(toInsertList);

                // 8. 循环插入用户和用户角色
                for (DsStudent student : toInsertList) {
                    // 创建新用户
                    SysUser newUser = new SysUser();
                    newUser.setUserName(student.getStudentNo());
                    newUser.setNickName(student.getStudentName());
                    newUser.setAnoId(student.getStudentId());
                    newUser.setCollegeId(Long.valueOf(student.getCollegeId()));

                    String password = StringUtils.isNotEmpty(student.getStudentPassword()) ?
                        student.getStudentPassword() : student.getStudentNo();
                    newUser.setPassword(SecurityUtils.encryptPassword("imut"+student.getStudentNo()));

                    if (StringUtils.isNotEmpty(student.getStudentSex())) {
                        newUser.setSex("男".equals(student.getStudentSex()) ? "0" : "1");
                    } else {
                        newUser.setSex("0");
                    }

                    newUser.setStatus("0");
                    newUser.setDelFlag("0");
                    newUser.setCreateBy(operName);
                    newUser.setCreateTime(now);

                    // 单条插入用户
                    sysUserMapper.insertUser(newUser);

                    // 创建用户角色关联
                    SysUserRole userRole = new SysUserRole();
                    userRole.setUserId(newUser.getUserId());
                    userRole.setRoleId(STUDENT_ROLE_ID);
                    userRoleList.add(userRole);
                }

                // 9. 批量插入用户角色关联
                if (!userRoleList.isEmpty()) {
                    sysUserRoleMapper.batchUserRole(userRoleList);
                }
            }

            // 10. 批量更新学生
            if (!toUpdateList.isEmpty()) {
                dsStudentMapper.batchUpdateStudent(toUpdateList);
            }

            long endTime = System.currentTimeMillis();
            return "成功导入" + successNum + "条数据，耗时" + (endTime - startTime) / 1000.0 + "秒";
        } catch (Exception e) {
            log.error("批量导入学生数据失败", e);
            throw new ServiceException("导入失败：" + e.getMessage());
        }
    }



    /**
     * 同步学生信息到用户表
     *
     * @param student 学生信息
     * @param operName 操作人
     * @param isUpdate 是否为更新操作
     */
    private void syncUserInfo(DsStudent student, String operName, boolean isUpdate)
    {

        try
        {
            // 查询是否已存在对应的用户
            SysUser existingUser = new SysUser();
            existingUser.setUserName(student.getStudentNo());
            List<SysUser> userList = sysUserMapper.selectUserList(existingUser);

            if (userList != null && !userList.isEmpty())
            {
                // 已存在，执行更新
                SysUser updateUser = userList.get(0);
                updateUser.setNickName(student.getStudentName());
                updateUser.setAnoId(student.getStudentId());
                updateUser.setCollegeId(Long.valueOf(student.getCollegeId()));
                // 如果学生性别不为空，则更新
                if (StringUtils.isNotEmpty(student.getStudentSex()))
                {
                    updateUser.setSex("男".equals(student.getStudentSex()) ? "0" : "1");
                }

                // 如果密码有变更，则重新加密
                if (StringUtils.isNotEmpty(student.getStudentPassword()) && !SecurityUtils.matchesPassword(student.getStudentPassword(), updateUser.getPassword()))
                {
                    updateUser.setPassword(SecurityUtils.encryptPassword(student.getStudentPassword()));
                }

                updateUser.setUpdateBy(operName);
                updateUser.setUpdateTime(DateUtils.getNowDate());
                sysUserMapper.updateUser(updateUser);
            }
            else if (!isUpdate)
            {
                // 不存在且为新增操作，添加用户
                SysUser newUser = new SysUser();
                newUser.setUserName(student.getStudentNo());
                newUser.setNickName(student.getStudentName());
                newUser.setAnoId(student.getStudentId());
                newUser.setCollegeId(Long.valueOf(student.getCollegeId()));

                // 设置密码
                String password = StringUtils.isNotEmpty(student.getStudentPassword()) ?
                    student.getStudentPassword() : student.getStudentNo(); // 如果没有密码则使用学号作为默认密码
                newUser.setPassword(SecurityUtils.encryptPassword("imut"+student.getStudentNo()));

                // 设置性别
                if (StringUtils.isNotEmpty(student.getStudentSex()))
                {
                    newUser.setSex("男".equals(student.getStudentSex()) ? "0" : "1");
                }
                else
                {
                    newUser.setSex("0"); // 默认性别为男
                }

                // 设置其他默认值
                newUser.setStatus("0"); // 正常状态
                newUser.setDelFlag("0"); // 未删除
                newUser.setCreateBy(operName);
                newUser.setCreateTime(DateUtils.getNowDate());

                // 插入用户
                sysUserMapper.insertUser(newUser);

                // 分配角色
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(newUser.getUserId());
                userRole.setRoleId(STUDENT_ROLE_ID);
                List<SysUserRole> userRoleList = new ArrayList<>();
                userRoleList.add(userRole);
                sysUserRoleMapper.batchUserRole(userRoleList);

            }
        }
        catch (Exception e)
        {
            log.error("同步学生信息到用户表失败", e);
            throw new ServiceException("同步学生信息到用户表失败: " + e.getMessage());
        }
    }

    @Override
    public List<String> selectAllClassNames() {
        return dsStudentMapper.selectAllClassNames();
    }

    @Override
    public List<DsStudent> selectStudentsByClassName(String className) {
        DsStudent student = new DsStudent();
        student.setClassName(className);
        return dsStudentMapper.selectDsStudentList(student);
    }

    // 根据用户名查询学生信息
    @Override
    public DsStudent selectDsStudentIdByUserName(DsStudent dsStudent) {
        return dsStudentMapper.selectDsStudentIdByUserName(dsStudent.getStudentNo());
    }
}
